package top.ruanlitao.shortlink.project.toolkit;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import jakarta.servlet.http.HttpServletRequest;
import top.ruanlitao.shortlink.project.common.constant.ShortLinkConstant;

import java.net.URI;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import java.util.Random;

/**
 * 短链接工具类
 */
public class ShortLinkUtil {

    /**
     * 获取链接缓存的过期时间
     * @param validDate 链接的有效期
     * @return 链接缓存的过期时间
     */
    public static long getLinkCacheExpireTime(LocalDateTime validDate) {
        // 如果 validDate 非空，计算与当前时间的差值（毫秒）
        long timeDifference = Optional.ofNullable(validDate)
                .map(each -> LocalDateTimeUtil.between(LocalDateTime.now(), validDate, ChronoUnit.MILLIS))
                .orElse(0L);

        // 计算基础过期时间
        long baseExpireTime = ShortLinkConstant.CACHE_VALID_TIME_ONE_WEEK;

        // 如果有时间限制且时间差小于一周，使用剩余时间；否则使用默认一周时间
        long expireTime = (validDate != null && timeDifference <= baseExpireTime)
                ? timeDifference
                : baseExpireTime;

        // 减去防止缓存穿透的随机时间
        return expireTime - getRandomLongMillis();
    }

    private static Long getRandomLongMillis() {
        Random random = new Random();
        int randomInt = random.nextInt(61);
        return (long) randomInt * 1000;
    }

    private static final String[] IP_HEADER_CANDIDATES = {
            "X-Original-Host",
            "X-Forwarded-For",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP",
            "HTTP_X_FORWARDED_FOR",
            "HTTP_CLIENT_IP"
    };


    /**
     * 获取用户真实IP
     *
     * @param request 请求
     * @return 用户真实IP
     */
    public static String getActualIp(HttpServletRequest request) {
        // 遍历所有候选HTTP头字段
        for (String header : IP_HEADER_CANDIDATES) {
            String ip = request.getHeader(header);
            if (ip != null && !ip.isEmpty()) {
                // 忽略大小写的"unknown"检查
                if (!"unknown".equalsIgnoreCase(ip)) {
                    // 处理逗号分隔的多个IP（取第一个有效IP）
                    for (String candidate : ip.split(",")) {
                        String trimmedIp = candidate.trim();
                        if (!trimmedIp.isEmpty() && !"unknown".equalsIgnoreCase(trimmedIp)) {
                            return trimmedIp;
                        }
                    }
                }
            }
        }
        // 所有头字段均无效时返回远程地址
        return request.getRemoteAddr();
    }

    /**
     * 获取用户访问操作系统
     *
     * @param request 请求
     * @return 访问操作系统
     */
    public static String getOs(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        if (userAgent.toLowerCase().contains("windows")) {
            return "Windows";
        } else if (userAgent.toLowerCase().contains("mac")) {
            return "Mac OS";
        } else if (userAgent.toLowerCase().contains("linux")) {
            return "Linux";
        } else if (userAgent.toLowerCase().contains("android")) {
            return "Android";
        } else if (userAgent.toLowerCase().contains("iphone") || userAgent.toLowerCase().contains("ipad")) {
            return "iOS";
        } else {
            return "Unknown";
        }
    }

    /**
     * 获取用户访问浏览器
     *
     * @param request 请求
     * @return 访问浏览器
     */
    public static String getBrowser(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        if (userAgent.toLowerCase().contains("edg")) {
            return "Microsoft Edge";
        } else if (userAgent.toLowerCase().contains("chrome")) {
            return "Google Chrome";
        } else if (userAgent.toLowerCase().contains("firefox")) {
            return "Mozilla Firefox";
        } else if (userAgent.toLowerCase().contains("safari")) {
            return "Apple Safari";
        } else if (userAgent.toLowerCase().contains("opera")) {
            return "Opera";
        } else if (userAgent.toLowerCase().contains("msie") || userAgent.toLowerCase().contains("trident")) {
            return "Internet Explorer";
        } else {
            return "Unknown";
        }
    }

    /**
     * 获取用户访问设备
     *
     * @param request 请求
     * @return 访问设备
     */
    public static String getDevice(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        if (userAgent.toLowerCase().contains("mobile")) {
            return "Mobile";
        }
        return "PC";
    }

    /**
     * 获取用户访问网络
     *
     * @param request 请求
     * @return 访问设备
     */
    public static String getNetwork(HttpServletRequest request) {
        String actualIp = getActualIp(request);
        // 这里简单判断IP地址范围，您可能需要更复杂的逻辑
        // 例如，通过调用IP地址库或调用第三方服务来判断网络类型
        return actualIp.startsWith("192.168.") || actualIp.startsWith("10.") ? "WIFI" : "Mobile";
    }

    /**
     * 获取原始链接中的域名
     * 如果原始链接包含 www 开头的话需要去掉
     *
     * @param url 创建或者修改短链接的原始链接
     * @return 原始链接中的域名
     */
    public static String extractDomain(String url) {
        String domain = null;
        try {
            URI uri = new URI(url);
            String host = uri.getHost();
            if (StrUtil.isNotBlank(host)) {
                domain = host;
                if (domain.startsWith("www.")) {
                    domain = host.substring(4);
                }
            }
        } catch (Exception ignored) {
        }
        return domain;
    }
}
